﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Web;
using Mvc4Demo.Models;
using MvcExtensions;

namespace Mvc4Demo.Core
{
    interface ILookupService
    {
        IEnumerable<Lookup> GetUserTypes();
    }

    public class LookupService : LookupProviderbase, ILookupService
    {
        public IEnumerable<Lookup> GetUserTypes()
        {
            return new List<Lookup>()
                {
                    new Lookup(){ Id = "1", Key = "A1", Description = "AAA111"},
                    new Lookup(){ Id = "2", Key = "A2", Description = "AAA112"},
                    new Lookup(){ Id = "3", Key = "A3", Description = "AAA113"},
                };
        }
    }

    public class LookupProviderbase
    {
        private static readonly ConcurrentDictionary<Type, IList<Lookup>> StaticCachedLookup = new ConcurrentDictionary<Type, IList<Lookup>>();

        public IEnumerable<Lookup> GetAccountTypes()
        {
            var enumType = typeof(AccountType);
            return StaticCachedLookup.GetOrAdd(enumType, (x) => GetEnumLookup(x).ToList());
        }


        public static IEnumerable<Lookup> GetEnumLookup<T>(T enumType)
            where T : Type
        {
            var returnList = new List<Lookup>();

            foreach (var fieldInfo in enumType.GetFields(BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public))
            {
                var lookup = new Lookup
                {
                    Id = Enum.Parse(enumType, fieldInfo.Name).ToString(),
                    Key = ((int)Enum.Parse(enumType, fieldInfo.Name)).ToString(),
                };
                var dscrAttributes = fieldInfo.GetCustomAttributes<DescriptionAttribute>().ToList();
                lookup.Description = dscrAttributes.Any() ? dscrAttributes.First().Description : fieldInfo.Name;
                returnList.Add(lookup);
            }

            return returnList;
        }
    }

    public class CacheProvider
    {
        public CacheProvider()
        {
            //DependencyResolver.Current.GetService<>()
        }
         
        public static TValue GetOrAdd<TValue>(string key, Func<string, TValue> valueFactory)
        {
            if (HttpContext.Current.Cache[key] != null)
            {
                return (TValue) HttpContext.Current.Cache[key];
            }
            var value = valueFactory(key);
            HttpContext.Current.Cache.Insert(key, value);
            return value;
        }

    }
}